import { h } from 'vue';

import { VbenIcon } from '@vben/icons';

import { z } from '#/adapter/form';

// 表单值类型
export interface FormValues {
  id?: number;
  parentId: number;
  menuType: 'C' | 'F' | 'M';
  icon?: string;
  menuName: string;
  sort: number;
  routePath?: string;
  componentPath?: string;
  isExternal: number;
  isShow: number;
  status: number;
  perms?: string;
  routeParams?: string;
  isCache: number;
}

// FormSchema类型定义
export interface FormSchema {
  component: string;
  fieldName: string;
  label?: string;
  rules?: any;
  defaultValue?: any;
  help?: string;
  componentProps?: any;
  dependencies?: any;
  renderComponentContent?: any;
}

// 菜单类型选项（M目录 C菜单 F按钮）
export const menuTypeOptions = [
  { label: '目录', value: 'M' },
  { label: '菜单', value: 'C' },
  { label: '按钮', value: 'F' },
];

// 是否选项
export const yesNoOptions = [
  { label: '是', value: 1 },
  { label: '否', value: 0 },
];

// 状态选项
export const statusOptions = [
  { label: '正常', value: 1 },
  { label: '停用', value: 2 },
];

// 显示状态选项
export const showOptions = [
  { label: '显示', value: 1 },
  { label: '隐藏', value: 0 },
];

// 表单schema定义
export type FormSchemaGetter = () => FormSchema[];

export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
    fieldName: 'id',
  },
  {
    component: 'TreeSelect',
    defaultValue: 0,
    fieldName: 'parentId',
    label: '上级菜单',
    rules: 'selectRequired',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: menuTypeOptions,
      optionType: 'button',
    },
    defaultValue: 'M',
    dependencies: {
      componentProps: (_: any, api: any) => {
        // 切换时清空校验
        Object.keys(api.errors.value).forEach((key) => {
          api.setFieldError(key, undefined);
        });
        return {};
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'menuType',
    label: '菜单类型',
  },
  {
    component: 'Input',
    dependencies: {
      // 类型不为按钮时显示
      show: (values: FormValues) => values.menuType !== 'F',
      triggerFields: ['menuType'],
    },
    renderComponentContent: (model: { icon: string }) => ({
      addonBefore: () => h(VbenIcon, { icon: model.icon }),
      addonAfter: () =>
        h(
          'a',
          {
            href: 'https://icon-sets.iconify.design/',
            target: '_blank',
          },
          '搜索图标',
        ),
    }),
    fieldName: 'icon',
    help: '点击搜索图标跳转到iconify & 粘贴',
    label: '菜单图标',
  },
  {
    component: 'Input',
    fieldName: 'menuName',
    label: '菜单名称',
    help: '支持i18n写法, 如: menu.system.user',
    rules: 'required',
  },
  {
    component: 'InputNumber',
    fieldName: 'sort',
    help: '排序, 数字越小越靠前',
    label: '显示排序',
    defaultValue: 0,
    rules: 'required',
  },
  {
    component: 'Input',
    componentProps: (model: { isExternal: number }) => {
      const placeholder =
        model.isExternal === 1
          ? '填写链接地址http(s)://  使用新页面打开'
          : '填写`路由地址`或者`链接地址`  链接默认使用内部iframe内嵌打开';
      return {
        placeholder,
      };
    },
    dependencies: {
      rules: (model: { isExternal: number; routePath?: string }) => {
        if (model.isExternal !== 1) {
          return z
            .string({ message: '请输入路由地址' })
            .refine((val) => !val.startsWith('/'), {
              message: '路由地址不需要带/',
            });
        }
        // 为链接
        return z
          .string({ message: '请输入链接地址' })
          .regex(/^https?:\/\//, { message: '请输入正确的链接地址' });
      },
      // 类型不为按钮时显示
      show: (values: FormValues) => values?.menuType !== 'F',
      triggerFields: ['isExternal', 'menuType'],
    },
    fieldName: 'routePath',
    help: `路由地址不带/, 如: menu, user\n 链接为http(s)://开头\n 链接默认使用内部iframe打开, 可通过{是否外链}控制打开方式`,
    label: '路由地址',
  },
  {
    component: 'Input',
    componentProps: (model: { isExternal: number }) => {
      return {
        // 为链接时组件disabled
        disabled: model.isExternal === 1,
      };
    },
    defaultValue: '',
    dependencies: {
      rules: (model: { isExternal: number; routePath?: string }) => {
        // 非链接时为必填项
        if (model.routePath && !/^https?:\/\//.test(model.routePath)) {
          return z
            .string()
            .min(1, { message: '非链接时必填组件路径' })
            .refine((val) => !val.startsWith('/') && !val.endsWith('/'), {
              message: '组件路径开头/末尾不需要带/',
            });
        }
        // 为链接时非必填
        return z.string().optional();
      },
      // 类型为菜单时显示
      show: (values: FormValues) => values.menuType === 'C',
      triggerFields: ['menuType', 'routePath'],
    },
    fieldName: 'componentPath',
    help: '填写组件路径, 如system/menu/index',
    label: '组件路径',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: yesNoOptions,
      optionType: 'button',
    },
    defaultValue: 0,
    dependencies: {
      // 类型不为按钮时显示
      show: (values: FormValues) => values.menuType !== 'F',
      triggerFields: ['menuType'],
    },
    fieldName: 'isExternal',
    help: '外链为http(s)://开头\n 选择是时，使用新窗口打开，选择否时使用iframe从内部打开页面',
    label: '是否外链',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: showOptions,
      optionType: 'button',
    },
    defaultValue: 1,
    dependencies: {
      // 类型不为按钮时显示
      show: (values: FormValues) => values.menuType !== 'F',
      triggerFields: ['menuType'],
    },
    fieldName: 'isShow',
    help: '隐藏后不会出现在菜单栏, 但仍然可以访问',
    label: '是否显示',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: statusOptions,
      optionType: 'button',
    },
    defaultValue: 1,
    dependencies: {
      // 类型不为按钮时显示
      show: (values: FormValues) => values.menuType !== 'F',
      triggerFields: ['menuType'],
    },
    fieldName: 'status',
    help: '停用后不会出现在菜单栏, 也无法访问',
    label: '菜单状态',
  },
  {
    component: 'Input',
    dependencies: {
      // 类型为菜单/按钮时显示
      show: (values: FormValues) => values.menuType !== 'M',
      triggerFields: ['menuType'],
    },
    fieldName: 'perms',
    help: `控制器中定义的权限字符\n 如: @SaCheckPermission("system:user:import")`,
    label: '权限标识',
  },
  {
    component: 'Input',
    componentProps: (model: { isExternal: number }) => ({
      // 为链接时组件disabled
      disabled: model.isExternal === 1,
      placeholder: '必须为json字符串格式',
    }),
    dependencies: {
      // 类型为菜单时显示
      show: (values: FormValues) => values.menuType === 'C',
      triggerFields: ['menuType'],
    },
    fieldName: 'routeParams',
    help: 'vue-router中的query属性\n 如{"name": "xxx", "age": 16}',
    label: '路由参数',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: yesNoOptions,
      optionType: 'button',
    },
    defaultValue: 0,
    dependencies: {
      // 类型为菜单时显示
      show: (values: FormValues) => values.menuType === 'C',
      triggerFields: ['menuType'],
    },
    fieldName: 'isCache',
    help: '路由的keepAlive属性',
    label: '是否缓存',
  },
];
